package cn.dt.ymcc.service.impl;

import cn.dt.ymcc.domain.CourseType;
import cn.dt.ymcc.dto.MbxDto;
import cn.dt.ymcc.mapper.CourseTypeMapper;
import cn.dt.ymcc.result.JSONResult;
import cn.dt.ymcc.service.ICourseTypeService;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author whale.dai
 * @since 2022-07-20
 */
@Service
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {
    @Autowired
    private CourseTypeMapper courseTypeMapper;
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    /**
     *使用注解
     */
    @Override
    @Cacheable(cacheNames="courseTypetreeData", key = "'courseTypetreeData'")
    public List<CourseType> treeData() {
        List<CourseType> tree = tree();
        return tree;
    }



    /**
     * 将无限极树存入redis
     * 1.查询内存中是否有数据，
     *  1.1没有数据直接从数据库中查询
     *  1.2有数据直接返回
     * @return
     * 这是缓存和数据库做一致的原始方法
     */
//    @Override
//    public List<CourseType> treeData() {
//        String treeKey = "courseTypetreeData";
//        Object obj = redisTemplate.opsForValue().get(treeKey);
//        if(obj!=null){
//            return  (List<CourseType>) obj;
//        }else{
//            List<CourseType> courseTypes = tree();
//            redisTemplate.opsForValue().set(treeKey,courseTypes);
//            return courseTypes;
//        }
//
//
//    }

    /**
     * 将无限极树抽离出来
     * @return
     */
    public List<CourseType> tree() {
        //1.查询到所有的对象，
        List<CourseType> allDate = courseTypeMapper.selectList(null);
        Map<Long, CourseType> allDepts = new HashMap<>();
        for (CourseType department : allDate) {
            allDepts.put(department.getId(),department);
        }
        ArrayList<CourseType> firstDepts = new ArrayList<>();
        for (CourseType temp : allDate) {
            //2.获取所有无父类的第一级
            if(temp.getPid()==null||temp.getPid().intValue()==0){
                firstDepts.add(temp);
            }else{
                //3.只要不是第一级就放到父级的children对象中
                CourseType parent = allDepts.get(temp.getPid());
                if(parent!=null){
                    parent.getChildren().add(temp);
                }
            }
        }
        return firstDepts;
    }

    /**
     * 面包屑实现
     *  1.封装courseType对象的dto还要带兄弟姐妹对象
     *  2.把dto封装成集合，
     *  3.通过前端传来的id（paramValue）去查询课程类型
     *  4.用查询到的对象去找到path字段并拆分出id（多个id）
     *  5.通过拆分出来的id分别查询出各自的对象（此处是批量查询出来的）
     *  6.遍历以后查询pid相等的所有字段即可
     *  7.将对应查出来的对象放到dto的list中
     * @param paramValue
     * @return
     */
    @Override
    public JSONResult crumbs(Long courseTypeId) {
        List<MbxDto> returnList = new ArrayList<>();
        /**
         * 1.入参校验
         * 2.根据当前课程分类ID查询课程分类详情
         * 3.得到id的path，分割path得到多个id的集合
         * 4.根据集合批量查询出多个分类对象
         * 5.循环分类，每次循环需要创建一个mbxDto，把当前分类装到ownerCourseType
         * 6.为当前分类查询同级分类列表，装到mbxDto的otherCourseTypes
         */
        //1.入参校验 @TODO
        //2.根据当前课程分类ID查询课程分类详情
        CourseType courseType = courseTypeMapper.selectById(courseTypeId);
        //3.得到id的path，分割path得到多个id的集合
        String[] split = courseType.getPath().split("\\.");
        //4.根据集合批量查询出多个分类对象
        List<CourseType> courseTypes = courseTypeMapper.selectBatchIds(Arrays.asList(split));
        //5.循环分类，每次循环需要创建一个mbxDto，把当前分类装到ownerCourseType
        for (CourseType coursetype:courseTypes
        ) {
            MbxDto mbxDto = new MbxDto();
            mbxDto.setOwnerCourseType(coursetype);
            //6.为当前分类查询同级分类列表，装到mbxDto的otherCourseTypes
            //根据pid查询 下面三行代码相当于手写sql：selset * from course_type where pid=? and id !=?
            Wrapper<CourseType> wrapper = new EntityWrapper<>();
            wrapper.eq("pid",coursetype.getPid())
                    .ne("id",coursetype.getId());
            List<CourseType> course = courseTypeMapper.selectList(wrapper);

            mbxDto.setOtherCourseTypes(course);

            returnList.add(mbxDto);
        }
        return JSONResult.success(returnList);

    }
}
